package com.cskaoyan.market.controller.wx;

import com.cskaoyan.market.annotation.ValidParam;
import com.cskaoyan.market.component.CloudService;
import com.cskaoyan.market.db.domain.MarketUser;
import com.cskaoyan.market.service.FlashMapFactory;
import com.cskaoyan.market.service.WxAuthService;
import com.cskaoyan.market.shiro.MarketToken;
import com.cskaoyan.market.util.ResponseUtil;
import com.github.pagehelper.util.StringUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;


@RestController
@RequestMapping("wx/auth")
public class WxAuthController {

    @Autowired
    WxAuthService wxAuthService;

    @Autowired
    SecurityManager securityManager;

    @Autowired
    CloudService cloudService;

    @Autowired
    FlashMapFactory flashMapFactory;


    //发送的是json字符串，接收json字符串

    @ValidParam
    @PostMapping("login")


    public Object login(@RequestBody @Valid MarketUser marketUser, BindingResult userBindingResult) {
        String username = marketUser.getUsername();
        String password = marketUser.getPassword();
        //校验之类的
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        MarketToken adminToken = new MarketToken(username, password,"wx");
        try {
            subject.login(adminToken);
        } catch (AuthenticationException e) {
            return ResponseUtil.fail(404, "用户名密码不正确");
//            throw new RuntimeException(e);
        }


        Session session = subject.getSession();
        MarketUser user = (MarketUser) subject.getPrincipal();

        session.setAttribute("user", user);

        Map<String,Object> data = new HashMap<>();
        Map<String,Object> userInfo = new HashMap<>();

        userInfo.put("nickName", user.getNickname());
        userInfo.put("avatarUrl", user.getAvatar());
        //token可以用session的编号，但是小程序不会携带cookie，所以session暂时用不了
        data.put("token", session.getId());
        data.put("userInfo", userInfo);
        return ResponseUtil.ok(data);
    }


    @PostMapping("logout")
    public Object logout() {

        Subject subject = SecurityUtils.getSubject();
        try {
            subject.logout();
        } catch (Exception e) {
            e.printStackTrace();


//        wxAuthService.logout(req.getHeader("X-CskaoyanMarket-Token"));

            return ResponseUtil.fail(404, "用户退出异常");
        }

        return ResponseUtil.ok();
    }
    @PostMapping("regCaptcha")
    public Object regCapcha(@RequestBody Map<String ,Object> map){
        String mobile = (String) map.get("mobile");

        Object attribute = flashMapFactory.getValue(mobile);
        if (attribute!=null){
            //验证码已经获取过
            LocalDateTime lifeTimeOfCode = (LocalDateTime)flashMapFactory.getValue("lifeTimeOfCode");
            if ((lifeTimeOfCode.plusMinutes(2)).isAfter(LocalDateTime.now())){
                //并未过期
                Map<String, Object> obj = new HashMap<String, Object>();
                obj.put("errno", 404);
                obj.put("errmsg", "验证码有效期为2分钟，请稍后获取");
            }
        }

        //向手机号发送验证码
        Random random = new Random();
        Integer randomNumber = random.nextInt(9000) + 1000;
        cloudService.sms(mobile, String.valueOf(randomNumber));
        flashMapFactory.putValue(mobile,randomNumber);
        flashMapFactory.putValue("lifeTimeOfCode",LocalDateTime.now());

        Object ok = ResponseUtil.ok();
        return ok;

    }

    @PostMapping("reset")
    public Object reset(@RequestBody Map<String,Object> data){
        String tempMobile = (String) data.get("mobile");
        String tempCode = (String) data.get("code");
        String password = (String) data.get("password");

        String realCode = String.valueOf(flashMapFactory.getValue(tempMobile));

        if (StringUtil.isEmpty(realCode)){
            Map<String, Object> obj = new HashMap<String, Object>();
            obj.put("errno", 703);
            obj.put("errmsg", "请先获取验证码");
            return obj;
        }
        LocalDateTime lifeTimeOfCode = (LocalDateTime)flashMapFactory.getValue("lifeTimeOfCode");
        if (!(lifeTimeOfCode.plusMinutes(2)).isAfter(LocalDateTime.now())){
            flashMapFactory.putValue(tempMobile,null);
            Map<String, Object> obj = new HashMap<String, Object>();
            obj.put("errno", 702);
            obj.put("errmsg", "验证码过期请重新获取");
            return obj;
        }
        if (!realCode.equals(tempCode)){
            Map<String, Object> obj = new HashMap<String, Object>();
            obj.put("errno", 706);
            obj.put("errmsg", "验证码错误");
            return obj;
        }

        Integer i=wxAuthService.reset(tempMobile,password);
        if (i==1){
            return ResponseUtil.ok();
        }
        return ResponseUtil.fail();
    }
    @PostMapping("register")
    public Object register(@RequestBody Map<String,Object> map) throws UnsupportedEncodingException {

        String tempMobile = (String) map.get("mobile");
        String tempCode = (String) map.get("code");

        String realCode = String.valueOf(flashMapFactory.getValue(tempMobile));

        if (StringUtil.isEmpty(realCode)){
            Map<String, Object> obj = new HashMap<String, Object>();
            obj.put("errno", 703);
            obj.put("errmsg", "请先获取验证码");
            return obj;
        }
        LocalDateTime lifeTimeOfCode = (LocalDateTime)flashMapFactory.getValue("lifeTimeOfCode");
        if (!(lifeTimeOfCode.plusMinutes(2)).isAfter(LocalDateTime.now())){
            flashMapFactory.putValue(tempMobile,null);
            Map<String, Object> obj = new HashMap<String, Object>();
            obj.put("errno", 702);
            obj.put("errmsg", "验证码过期请重新获取");
            return obj;
        }
        if (!realCode.equals(tempCode)){
            Map<String, Object> obj = new HashMap<String, Object>();
            obj.put("errno", 706);
            obj.put("errmsg", "验证码错误");
            return obj;
        }

        MarketUser newUser=wxAuthService.register(map);
        if ("      ".equals(newUser.getUsername())){
            Map<String, Object> obj = new HashMap<String, Object>();
            obj.put("errno", 705);
            obj.put("errmsg", "用户名已注册");
            return obj;
        }

        String username = newUser.getUsername();
        String password = newUser.getPassword();
//todo
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            subject.login(token);
        } catch (AuthenticationException e) {
            return ResponseUtil.fail(404, "用户名密码不正确");
//            throw new RuntimeException(e);
        }


        MarketUser user = (MarketUser) subject.getPrincipal();

        session.setAttribute("user", user);

        Map<String,Object> data = new HashMap<>();
        Map<String,Object> userInfo = new HashMap<>();

        userInfo.put("nickName", user.getNickname());
        userInfo.put("avatarUrl", user.getAvatar());
        //token可以用session的编号，但是小程序不会携带cookie，所以session暂时用不了
        data.put("token", session.getId());
        data.put("userInfo", userInfo);
        return ResponseUtil.ok(data);

    }
}
